﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MessageCallAspect.Inspector.Attributes;
using System.Threading;
using MessageCallAspect.Aspect.Cache;
using MessageCallAspect.Aspect.Trace;
using MessageCallAspect.Inspector.Request;
using MessageCallAspect.Inspector;
using System.Reflection;
using System.Linq.Expressions;
using System.Runtime.Remoting.Messaging;
using Syk.Library.Extensions;
using MessageCallAspect.Demo.Aspect;
namespace MessageCallAspect.Demo
{ 
    class Program
    {
        static void Main(string[] args)
        {
            ServiceInspectorsContext moduleContext = new ServiceInspectorsContext();
            ICalculator calc = new Calculator();

            moduleContext.AddService(calc, true);
            ICalculator transparentCalc = moduleContext.GetService<ICalculator>();
            /* tracing and loging */
            transparentCalc.Init();


            /* call ICachePolicy to decide if need to cache the result*/
            var res = transparentCalc.Abs(-1);

            /* method call and cache the result*/
            transparentCalc.Subtraction(1, 1);

            /* result from cache */
            transparentCalc.Subtraction(1, 1);

            Thread.Sleep(TimeSpan.FromMinutes(0.06));

            /* method call and cache the result*/
            transparentCalc.Subtraction(1, 1);

            /* no inspection for current operation*/
            transparentCalc.Division(4, 2);


            double result;
            /* tracing and loging */
            transparentCalc.Division(4, 2, out result);
            try
            {
                /* trace and log the exception*/
                transparentCalc.Division(4, 0, out result);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }

            string returnValue = transparentCalc.Dummy(1, 1, out result);


            transparentCalc.Dummy1(666);
           // moduleContext.Dispose();
            Console.ReadLine();

        }
    }

    public interface IICalculator1
    {
        int Dummy1(int a);
    }
    public interface ICalculator : IICalculator1, IDisposable
    {
        void Init();
        int Subtraction(int a, int b);
        decimal Abs(decimal a);
        double Division(int a, int b);
        void Division(int a, int b, out double result);
        string Dummy(int a, int b, out double result);
    }

    [TraceAspect]
    public class Calculator : ICalculator 
    {
        #region ICalculator Members

        [LicenseEnforceAspect(Order= 1)]
        public void Init()
        {
        }

        [CacheAspect(TimeoutMinute = 0.05)]
        public int Subtraction(int a, int b)
        {
            return a + b;
        }

        [CacheAspect(typeof(AbsCachePolicy), TimeoutMinute = 1)]
        public decimal Abs(decimal a)
        {
            return Math.Abs(a);
        }

        [InspectorIgnore]
        public double Division(int a, int b)
        {
            return a / b;
        }

        public void Division(int a, int b, out double result)
        {
            result = a / b;
        }

        public string Dummy(int a, int b, out double result)
        {
            result = 666;
            return "IsDummy";
        }
        #endregion

        #region IDisposable Members

        public void Dispose()
        {
            
        }

        #endregion

        #region IICalculator1 Members

        [TraceAspect(TraceAspectCondition=TraceAspectCondition.AfterInvoke| TraceAspectCondition.BeforeInvoke| TraceAspectCondition.Parameters)]    
        public int Dummy1(int a)
        {
            return a;
        }

        #endregion
    }

    public class AbsCachePolicy : ICachePolicy
    {
        public AbsCachePolicy()
        {

        }
        #region ICachePolicy Members

        public bool AllowCaching(object returnValue)
        {
            if ((decimal)returnValue == 1)
            {
                return false;
            }
            else
            {
                return true;
            }
        }

        #endregion
    }

}

